home *** CD-ROM | disk | FTP | other *** search
- Path: lrz-muenchen.de!news
- From: watzka@stat.uni-muenchen.de (Kurt Watzka)
- Newsgroups: comp.lang.c
- Subject: Re: Why does my program do this?
- Date: 1 Apr 1996 17:21:43 GMT
- Organization: Leibniz-Rechenzentrum, Muenchen (Germany)
- Distribution: world
- Message-ID: <4jp3b7$ja7@sparcserver.lrz-muenchen.de>
- References: <4jnln2$95j@dfw-ixnews3.ix.netcom.com>
- NNTP-Posting-Host: sun2.lrz-muenchen.de
-
- ishky@ix.netcom.com(Andrew Heiz ) writes:
-
- >Hi again,
-
- >There have been so many helpful readers out there here is another
- >question for you.
-
- >I've declared an 2 dimentional array:
-
- >char scores[STUDENT][5];
-
- >I am entering the scores in 2 for loops like this:
-
- > for (i=0; i <= students-1; i=i+1)
-
- 1) Is "students" somehow related to "STUDENT"? If yes, why do you
- present both?
-
- 2) "i++" _is_ a common idiom in C. Get used to it.
-
- 3) A less common idiom, but quite useful for "looping over all
- elements of an array of STUDENT elements is
-
- for (i = 0; i < STUDENT; i++)
-
- This is a question of style, but it makes the relation to
- the number of elements in an array more obvious, imho.
-
- > {
- > for (j=0; j <= tests-1; j=j+1)
- > {
- > gets(&scores[i][j];
-
- 1) "scores" is an array of STUDENT arrays of 5 chars, so
- "scores[i][j]" is _one_ char. The only string that
- can be stored in _one_ char is the empty string.
-
- 2) Don't use gets(), use fgets() to check that the users
- really enters an empty string:
-
- fgets(&scores[i][j], 1, stdin);
-
- This will not allow much user interaction in most implementations,
- btw.
-
- 3) Maybe you want to allow nonempty input. One way to do this
- is
-
- #include <stdlib.h>
- #include <string.h>
-
- char *scores[STUDENT][5];
-
- and inside your inner loop:
-
- char tmp[A_BIG_NUMBER], *newline;
-
- fgets(tmp, sizeof tmp, stdin);
- newline = strchr(tmp, '\n');
- if (newline)
- *newline = '\0';
- else
- /* die */;
- scores[i][j] = malloc(strlen(tmp) + 1);
- if (scores[i][j])
- strcpy(scores[i][j], tmp);
- else
- /* die */
-
- > }
- > }
-
- >I print out the scores in the same type of loop structure:
-
- > for (i=0; i <= students-1; i=i+1)
- > {
- > printf("Scores for student %d",i+1);
- > for (j=0; j <= tests-1; j=j+1)
- > {
- > printf("\tGrade %d: %s",j+1,scores[i][j]);
- ^^^^^^ ???
- > }
- > }
-
- >I am getting (if you don't already know this):
-
- I did not expect this, and I don't belief it, either. At the position
- marked with (???), your compiler inserts the magical address of operator,
- not available in most implementations of C that I know. You promised
- to pass a pointer to char to printf(), but you really passed an int.
- If that int holds the address (remember that transformation of an
- int to a pointer is defined only for one constant value) of the char
- that was passed to printf() as an int, real magic is at work.
-
- > Scores for student 1: Grade 1: 999991 Grade 2: 99991 Grade
- >3: 9991 Grade 4: 991 Grade 5: 91
-
- This is the expected output for "&scores[i][j]".
-
- >Is my data being mangled some how in the data entry? I've tried just
- >printing out 1 array element or not using the loop and naming each
- >element but nothing seems to work.
-
- If your user does not enter an empty string for the last grade of the
- last student, or a string of more than one char for the last but one
- grade of the last student, of a string of more than two chars for the
- last but two grade of the last student, etc., you are going to write
- to memory that does not belong to you. I dont know about the grading
- system in your country, but if grades can have more than zero digits,
- you are going to write to memory that you dont want to write to most
- of the time. If grades are one digit entities, adding one extra
- student and _not_ treating the elements of "scores" as strings might
- "work", but it is still very _bad_ practice.
-
- Kurt
- --
- | Kurt Watzka Phone : +49-89-2180-6254
- | watzka@stat.uni-muenchen.de
-